//package personal.abandoned;
//
//
//import personal.scanner.ScannerFiniteAutomata;
//
//import java.util.*;
//
//import static personal.abandoned.StandardRE.*;
//
///**
// * 扩展正则表达式类，将扩展型正则表达式转化成标准正则表达式。
// * 标准正则表达式：int[]。 - 使用 -'e' 表示空串。 - 只有()*|运算，其值是对应原生字符的负值。 - 其余正数值一律为原生字符。
// * 扩展正则表达式：string。 - \e 表示空串。 - 将 ()*|- 视为运算符。 - 反而，上述运算符的原生字符需要通过转义给出，例如：\*。
// *
// * @author 陈渤林
// */
//public class ExREToStREConverter {
//
//    enum AcceptType {
//        NORMAL_CHAR, EMPTY_STR, OPERATOR_CHAR, RANGE_UNION,
//    }
//
//
//    /**
//     * 正则表达式使用的关键字
//     */
//    public static final Set<Integer> RE_KEY = new HashSet<Integer>(Arrays.asList(EMPTY_STR, LEFT_BRACKET, RIGHT_BRACKET, CLOSURE, UNION));
//
//    /**
//     * 结果的 buffer
//     */
//    private static StandardRE standardRE = null;
//
//
//    /**
//     * 扩展 re 转标准 re 的自动机，是手搓的
//     */
//    static final ScannerFiniteAutomata trans = makeTrans();
//
//    /**
//     * 构建转换自动机
//     */
//    static ScannerFiniteAutomata makeTrans() {
//        ScannerFiniteAutomata ret = new ScannerFiniteAutomata();
//
//        // 添加边
//        for (int trans = 1; trans < 128; ++trans) {
//            if (trans == '\\') ret.addEdge(1, 2, trans);
//            else if (trans == '(' || trans == ')' || trans == '*' || trans == '|') ret.addEdge(1, 4, trans);
//            else if (trans == '-') ret.addEdge(1, 5, trans);
//            else ret.addEdge(1, 1, trans);
//        }
//        ret.addEdge(2, 1, '(');
//        ret.addEdge(2, 1, ')');
//        ret.addEdge(2, 1, '*');
//        ret.addEdge(2, 1, '|');
//        ret.addEdge(2, 1, '-');
//        ret.addEdge(2, 1, '\\');
//        ret.addEdge(2, 3, 'e');
//        for (int trans = 1; trans < 128; ++trans)
//            ret.addEdge(5, 6, trans);
//        ret.setStartId(1); // 设置起点
//        // 初始化接受节点
//        ret.registerAcceptableNode(1, AcceptType.NORMAL_CHAR.ordinal());
//        ret.registerAcceptableNode(3, AcceptType.EMPTY_STR.ordinal());
//        ret.registerAcceptableNode(4, AcceptType.OPERATOR_CHAR.ordinal());
//        ret.registerAcceptableNode(6, AcceptType.RANGE_UNION.ordinal());
//        ret.initTransitionTable();
//        ret.handles.putIfAbsent( // 普通字符
//                AcceptType.NORMAL_CHAR.ordinal(), (ch) -> {
//                    standardRE.add((int) ch);
//                });
//        ret.handles.putIfAbsent( // 空串
//                AcceptType.EMPTY_STR.ordinal(), (ch) -> {
//                    standardRE.add((int) EMPTY_STR);
//                });
//        ret.handles.putIfAbsent( // 标准运算符
//                AcceptType.OPERATOR_CHAR.ordinal(), (ch) -> {
//                    standardRE.add(-(int) ch);
//                });
//        ret.handles.putIfAbsent( // -，范围或
//                AcceptType.RANGE_UNION.ordinal(), (ch) -> {
//                    int l = standardRE.get(standardRE.size() - 1) + 1, r = (int) ch;
//                    if (l > r) {
//                        r = l;
//                        l = (int) ch;
//                    }
//                    for (int i = l; i <= r; ++i) {
//                        standardRE.add(UNION);
//                        standardRE.add((int) i);
//                    }
//                });
//        return ret;
//
//    }
//
//
//    /**
//     * 传入扩展正则表达式，返回标准正则表达式
//     *
//     * @param x 扩展正则表达式
//     * @return 标准正则表达式
//     * @throws ArrayIndexOutOfBoundsException 转移字符超出转移表下标，我们暂时不支持中文，详见自动机生成转移表{@link ScannerFiniteAutomata#initTransitionTable() }
//     * @throws InputMismatchException         非法输入
//     */
//    StandardRE convert(String x) throws ArrayIndexOutOfBoundsException, InputMismatchException {
//        this.standardRE = new StandardRE();
//        try { // 防止出错
//            int u = 1; // 当前序号
//            for (int i = 0; i < x.length(); ++i) {
//                char ch = x.charAt(i);
////                System.out.println(String.format("%d %c", u, ch));
//                u = this.trans.transitionTable[u][ch]; // 转移
//                if (u == 0)
//                    throw new InputMismatchException(String.format("存在非法输入，请检查字符串 %s 字符 %c 附近的语法", x, ch));
//                if (this.trans.isAcceptable(u)) { // 是可接受节点
//                    int accId = this.trans.getAcceptNodes().get(u);
//                    this.trans.handles.get(accId).todo(ch);
//                    u = this.trans.getStartId(); // 这是对 nfa 的空串转移的特殊处理
//                }
//            }
//        } catch (ArrayIndexOutOfBoundsException e) {
//            String tmp = "转移字符超出转移表下标，我们暂时不支持中文，详见自动机生成转移表{@link FiniteAutomata#init() }";
//            throw new ArrayIndexOutOfBoundsException(tmp);
//        }
//        return this.standardRE;
//    }
//
//    public Set<Integer> getTransitions() {
//        Set<Integer> ret = new HashSet<Integer>();
//        for (Integer tmp : this.standardRE) {
//            if (tmp > 0) ret.add(tmp);
//        }
//        return ret;
//    }
//}
